package com.huawei.zyb.taskManager.infrastructure.persistence.repository;

import com.huawei.zyb.taskManager.domain.project.entity.Project;
import com.huawei.zyb.taskManager.domain.project.repository.ProjectRepository;
import com.huawei.zyb.taskManager.domain.project.valueobject.*;
import com.huawei.zyb.taskManager.domain.developer.valueobject.DeveloperId;
import com.huawei.zyb.taskManager.infrastructure.persistence.mapper.ProjectMapper;
import com.huawei.zyb.taskManager.infrastructure.persistence.po.ProjectPO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 项目仓储实现
 */
@Repository
public class ProjectRepositoryImpl implements ProjectRepository {
    
    @Autowired
    private ProjectMapper projectMapper;
    
    @Override
    public Project save(Project project) {
        ProjectPO projectPO = toProjectPO(project);
        if (projectPO.getId() == null || !existsById(project.getId())) {
            projectMapper.insert(projectPO);
        } else {
            projectMapper.update(projectPO);
        }
        return project;
    }
    
    @Override
    public Optional<Project> findById(ProjectId projectId) {
        ProjectPO projectPO = projectMapper.findById(projectId.getValue());
        return projectPO != null ? Optional.of(toProject(projectPO)) : Optional.empty();
    }
    
    @Override
    public List<Project> findByManagerId(String managerId) {
        List<ProjectPO> projectPOs = projectMapper.findByManagerId(managerId);
        return projectPOs.stream().map(this::toProject).collect(Collectors.toList());
    }
    
    @Override
    public List<Project> findByStatus(ProjectStatus status) {
        List<ProjectPO> projectPOs = projectMapper.findByStatus(status.name());
        return projectPOs.stream().map(this::toProject).collect(Collectors.toList());
    }
    
    @Override
    public List<Project> findAll() {
        List<ProjectPO> projectPOs = projectMapper.findAll();
        return projectPOs.stream().map(this::toProject).collect(Collectors.toList());
    }
    
    @Override
    public List<Project> findByNameContaining(String namePattern) {
        List<ProjectPO> projectPOs = projectMapper.findByNameLike(namePattern);
        return projectPOs.stream().map(this::toProject).collect(Collectors.toList());
    }
    

    
    @Override
    public void deleteById(ProjectId projectId) {
        projectMapper.deleteById(projectId.getValue());
    }
    
    @Override
    public boolean existsById(ProjectId projectId) {
        return projectMapper.existsById(projectId.getValue());
    }
    
    @Override
    public boolean hasIncompleteRequirements(ProjectId projectId) {
        return projectMapper.hasIncompleteRequirements(projectId.getValue());
    }
    

    
    /**
     * 将领域对象转换为持久化对象
     */
    private ProjectPO toProjectPO(Project project) {
        ProjectPO projectPO = new ProjectPO();
        if (project.getId() != null) {
            projectPO.setId(project.getId().getValue());
        }
        projectPO.setName(project.getName().getValue());
        projectPO.setDescription(project.getDescription() != null ? project.getDescription().getValue() : null);
        projectPO.setStatus(project.getStatus().name());
        projectPO.setManagerId(project.getManagerId() != null ? project.getManagerId().getValue() : null);
        projectPO.setCreatedAt(project.getCreatedAt());
        projectPO.setUpdatedAt(project.getUpdatedAt());
        return projectPO;
    }
    
    /**
     * 将持久化对象转换为领域对象
     */
    private Project toProject(ProjectPO projectPO) {
        return Project.restore(
            ProjectId.of(projectPO.getId()),
            ProjectName.of(projectPO.getName()),
            projectPO.getDescription() != null ? ProjectDescription.of(projectPO.getDescription()) : null,
            ProjectStatus.valueOf(projectPO.getStatus()),
            projectPO.getManagerId() != null ? DeveloperId.of(projectPO.getManagerId()) : null,
            projectPO.getCreatedAt(),
            projectPO.getUpdatedAt()
        );
    }
}